from django.conf import settings
from djwatch.models import Check
from djwatch.utils import round_to_minutes, xdaterange
from urllib import urlencode
import datetime
import math
import random
import string
import urllib2

class GraphData(object):
    def __init__(self, title, titles):
        self.title = title
        self.titles = list(titles)
        self.rows = [[] for _ in titles]  # [[(time, value), (time, value), ...], [(time, value), (time, value), ...]]
        self.min = 0
        self.max = 1

    def update_max(self, value):
        self.max = max(self.max, value)

    def get_colors(self):
        return self.colors[:len(self.title)]

def get_times(hours):
    end_date = round_to_minutes(datetime.datetime.now())
    start_date = end_date - datetime.timedelta(hours=hours)
    return list(xdaterange(start_date, end_date, step=datetime.timedelta(minutes=1)))

def get_server_stat(times, server_id):
    """
    [(time, data), (time, data)]
    """
    checks = Check.objects.filter(server__id=server_id, datetime__gt=times[0], datetime__lt=times[-1])
    return [(round_to_minutes(x.datetime), x.get_data()) for x in checks if x.data]
#    return [stat_by_time.get(dt, {}) for dt in times]

def compose_static_image(
    graph_data,
    times,
    size=(500, 200),
    axis=(10, 10),
    default_maxX=100,
    default_maxY=100,
    trunc_data=1,
    trunc_data_label=60,
):
    random_id = ''.join(random.choice(string.letters) for _ in range(64))
    url = 'http://chart.apis.google.com/chart?chid=%s' % random_id

    time_titles = []
    time_titles2 = []
    offset = 0
    offset_found = False
    for t in times:
        if t.minute % trunc_data_label == 0:
            offset_found = True
            time_titles.append('%02d:%02d' % (t.hour, t.minute))
            time_titles2.append('%02d:%02d' % (t.hour, t.minute))
        else:
            if not offset_found:
                offset += 1
            time_titles2.append('')

    # chd=t:<line_1_x1>,<line_1_x2>,...|<line_1_y1>,<line_1_y2,...|
    # <line_2_x1>,<line_2_x2>,...|<line_2_y1>,<line_2_y2>,...
    data = []
    time2number = dict((t, i) for i, t in enumerate(times))
    n = len(times)
    for row in graph_data.rows:
        xs = []
        ys = []
        for i, (t, value) in enumerate(row):
            if i % trunc_data == 0:
                xs.append('%.02f' % (float(time2number[t] * default_maxX) / n))
                ys.append('%.02f' % (float(value * default_maxY) / graph_data.max))
        data.append(','.join(xs))
        data.append(','.join(ys))
    # docs: http://code.google.com/intl/en/apis/chart/docs/gallery/line_charts.html
    post = {
        'cht': 'lxy',
        'chd':  't:%s' % '|'.join(data),
        'chdl': u'|'.join(graph_data.titles),
        'chg': '%.02f,10,4,1,%.02f,0' % (math.floor(100.0 / len(time_titles)), float(offset) * default_maxX / n),
        'chma': '60,20,20,30|110,20',
        'chs': '%sx%s' % size,
        'chtt': graph_data.title,
        'chxl': '0:|%s|' % '|'.join(time_titles2),
        'chxr': '0,%d,%d|1,%f,%f' % (0, len(times), graph_data.min, graph_data.max),
        'chxt': 'x,y',
        'chdlp': 'b',
        'chco': ','.join(settings.GRAPH_COLORS),
        'chls': '|'.join([
            '1,1,0',
#            '2,1,0',
#            '2,10,10',
        ]),
    }
    if settings.ENABLE_GRAPH_MARKERS:
        post['chm'] = '|'.join('o,%s,%d,-1,3' % (x, i) for i, x in enumerate(settings.GRAPH_COLORS))

#    print post
    encoded_post = urlencode([(k, v.encode('utf-8')) for k, v in post.items()])
    #print len(encoded_post)
    if len(encoded_post) >= MAX_GOOGLECHARTS_DATA_SIZE:
        #print 'trunc...'
        return compose_static_image(
            graph_data,
            times,
            size,
            axis,
            default_maxX,
            default_maxY,
            trunc_data=trunc_data * 2,
        )
    return urllib2.urlopen(url, encoded_post).read()

MAX_GOOGLECHARTS_DATA_SIZE = 16 * 1024
